﻿using System;
using System.Management;
using ClusterAwareProperties;
using ClusterAwareProperties.Properties;

namespace ClusterAwareProperties
{
    /// <summary>
    /// Wrapper class Resource ManagementObject
    /// </summary>
    public class ResourceProperty : IDisposable
    {

        #region private property

        private readonly ManagementObject _classInstance;
        private string _typeresource;

        #endregion

        #region ctor


        /// <summary>
        /// Constructor
        /// </summary>
        private ResourceProperty()
        {
            Characteristics = CharacteristicsResource.Unknown;
            RestartAction = RestartAct.StateUnknown;
            State = StateResources.StateUnknown;
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="queryobj">Resource ManagementObject instance</param>
        public ResourceProperty(ManagementObject queryobj)
            : this()
        {
            var path = queryobj.ToString();
            if (path.IndexOf("\\root\\MSCluster:MSCluster_Resource") == -1)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_TypeClassInvalid, path, "\\root\\MSCluster:MSCluster_Resource"));
            }
            _classInstance = queryobj;
            this.Convert(queryobj);
        }

        #endregion

        #region public properties

        /// <summary>
        /// Return instance of Resource ManagementObject
        /// </summary>
        public ManagementObject Instance
        {
            get { return _classInstance; }
        }

        /// <summary>
        /// Provides a short textual description of the resource.
        /// </summary>
        public string Caption { get; internal set; }

        /// <summary>
        /// Indicates when the resource was installed. A lack of a value does not indicate that the resource is not installed.
        /// </summary>
        public DateTime? InstallDate { get; internal set; }

        /// <summary>
        /// Indicates the current status of the resource.
        /// </summary>
        public StatusResource Status { get; internal set; }

        /// <summary>
        /// Describes the flags set for the resource
        /// </summary>
        public UInt32 Flags { get; set; }

        /// <summary>
        /// Describes the characteristics of the resource
        /// </summary>
        public CharacteristicsResource Characteristics { get; set; }

        /// <summary>
        /// Provides the name of the resource.
        /// </summary>
        public string Name { get; internal set; }

        /// <summary>
        /// Provides access to the resource's Description property.
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// Provides access to the resource's DebugPrefix property.
        /// </summary>
        public string DebugPrefix { get; set; }

        /// <summary>
        /// Provides access to the resource's IsAlivePollInterval property, which is the recommended interval in milliseconds at which the Cluster Service should poll the resource to determine whether it is operational. 
        /// </summary>
        ///<remarks>
        /// If the property is set to 0xFFFFFFFF, the Cluster Service uses the IsAlivePollInterval property for the resource type associated with the resource.
        /// </remarks>      
        public UInt32 IsAlivePollInterval { get; set; }

        /// <summary>
        /// Provides access to the resource's LooksAlivePollInterval property, which is the recommended interval in milliseconds at which the Cluster Service should poll the resource to determine whether it appears operational.
        /// </summary>
        /// <remarks>
        /// If the property is set to 0xFFFFFFFF, the Cluster Service uses the LooksAlivePollInterval property for the resource type associated with the resource.
        /// </remarks>
        public UInt32 LooksAlivePollInterval { get; set; }

        /// <summary>
        /// Provides access to the resource's PersistentState property, which specifies whether the resource should be brought online or left offline when the Cluster Service is started.
        /// </summary>
        /// <remarks>
        /// This property is not supported before Windows Server 2008.
        /// </remarks>
        public UInt32? PendingTimeout { get; set; }

        /// <summary>
        /// Provides the process ID of the resource host service that is currently hosting the resource.
        /// </summary>
        ///<remarks>
        /// This property is not supported before Windows Server 2008.
        /// </remarks>
        public UInt32? MonitorProcessId { get; set; }

        /// <summary>
        /// Provides access to the resource's PersistentState property, which specifies whether the resource should be brought online or left offline when the Cluster Service is started.
        /// </summary>
        public bool PersistentState { get; set; }

        /// <summary>
        /// Provides access to the resource's RestartAction property, which is the action to be taken by the Cluster Service if the resource fails. 
        /// </summary>
        public RestartAct RestartAction { get; set; }

        /// <summary>
        /// Provides access to the resource's RestartPeriod property, which is interval of time, in milliseconds, during which a specified number of restart attempts can be made on a nonresponsive resource.
        /// </summary>
        public UInt32 RestartPeriod { get; set; }

        /// <summary>
        /// Provides access to the resource's RestartThreshold property which is the maximum number of restart attempts that can be made on a resource within an interval defined by the RestartPeriod property before the Cluster Service initiates the action specified by the RestartAction property.
        /// </summary>
        public UInt32 RestartThreshold { get; set; }

        /// <summary>
        /// Provides access to the resource's RetryPeriodOnFailure property, which is the interval of time (in milliseconds) that a resource should remain in a failed state before the Cluster service attempts to restart it.
        /// </summary>
        public UInt32 RetryPeriodOnFailure { get; set; }

        /// <summary>
        /// Provides access to the resource's SeparateMonitor property, which indicates whether the resource requires its own Resource Monitor.
        /// </summary>
        public bool SeparateMonitor { get; set; }

        /// <summary>
        /// the resource's Type property, which is the name for the resource's type.
        /// </summary>
        public string Type
        {
            get { return _typeresource;}
            set
            {
                _typeresource = value;
                WindowsType = ResourceTypeNamesConstants.ConvertToWindowsResourceType(value);
            } 
        }

        /// <summary>
        /// Provides access the resource's Type which is enum windows resource's type.
        /// </summary>
        public WindowsResourcetype WindowsType { get; internal set; }

        /// <summary>
        /// The current state of the resource. The following are the possible values. 
        /// </summary>
        public StateResources State { get; internal set; }

        /// <summary>
        /// The current internal state of the resource.
        /// </summary>
        /// <remarks>
        /// This property is not supported before Windows Server 2008.
        /// </remarks>
        public string InternalState { get; internal set; }

        /// <summary>
        /// Gets or sets the resource class of a resource.
        /// </summary>
        public UInt32 ResourceClass { get; set; }

        /// <summary>
        /// Provides the list of references to nodes that can be the owner of this resource.
        /// </summary>
        public UInt32 Subclass { get; set; }

        /// <summary>
        /// Provides access to the private properties of the resource.
        /// </summary>
        public PrivatePropertiesData PrivateProperties { get; set; }

        /// <summary>
        /// Provides a list of crypto checkpoints for the resource.
        /// </summary>
        public string[] CryptoCheckpoints { get; internal set; }

        /// <summary>
        /// Provides a list of registry checkpoints for the resource.
        /// </summary>
        public string[] RegistryCheckpoints { get; internal set; }

        /// <summary>
        /// The resource can be selected as the quorum resource for the cluster.
        /// </summary>
        public bool QuorumCapable { get; set; }

        /// <summary>
        /// The resource can be selected as the quorum resource in clusters configured using the -localquorum switch.
        /// </summary>
        public bool LocalQuorumCapable { get; set; }

        /// <summary>
        /// If True, the resource cannot be deleted unless all nodes are active. 
        /// Setting this property to True adds the CLUS_CHAR_DELETE_REQUIRES_ALL_NODES characteristic to the resource.
        /// </summary>
        public bool DeleteRequiresAllNodes { get; set; }

        /// <summary>
        /// If True, indicates that the resource is essential to the cluster and cannot be deleted.
        /// </summary>
        public bool CoreResource { get; set; }

        /// <summary>
        /// Indicates the length of time to wait, in milliseconds, before declaring a deadlock in any call into a resource.
        /// </summary>
        /// <remarks>
        /// This property is not supported before Windows Server 2008.
        /// </remarks>
        public UInt32? DeadlockTimeout { get; set; }

        /// <summary>
        /// Provides a resource-specific status message that complements the current resource state.
        /// </summary>
        public string ResourceSpecificStatus { get; internal set; }

        /// <summary>
        /// Indicates the time delay before a failed resource is restarted.
        /// </summary>
        /// <remarks>
        /// This property is not supported before Windows Server 2008.
        /// </remarks>
        public UInt32? RestartDelay { get; internal set; }

        /// <summary>
        /// Specifies if the resource is a cluster shared volume resource.
        /// </summary>
        /// <remarks>
        /// This property is not supported before Windows Server 2008 R2.
        /// </remarks>
        public bool? IsClusterSharedVolume { get; internal set; }

        #endregion

        #region IDisposable Members

        /// <summary>
        /// Dispose Class
        /// </summary>
        public void Dispose()
        {
            if (Instance != null)
            {
                Instance.Dispose();
            }

        #endregion
        }
    }
}
